home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.qualcomm.com
/
2014.06.ftp.qualcomm.com.tar
/
ftp.qualcomm.com
/
eudora
/
developers
/
emsapi
/
carbon_emsapi.sit.hqx
/
Macintosh API Support
/
file1847.c
< prev
next >
Wrap
Text File
|
2001-03-08
|
22KB
|
720 lines
/* ======================================================================
Functions to manage MIME type data structures for use
with Eudora translation API on the Mac.
Filename: file1847.c
Last Edited: March 7, 1997
Authors: Scott Manjourides
Copyright: 1995, 1996 QUALCOMM Inc.
Technical support: <emsapi-info@qualcomm.com>
*/
#include <string.h>
#include "emsapi-mac.h"
#include "mimetype.h"
#include "ctencode.h"
#include "rfc822.h"
#include "rfc1847.h"
#include "file1847.h"
/* ------------------------------------------------------------------------ */
typedef struct {
Boolean bFoundHeader;
BufTypeHandle bufH, searchBufH;
TrEncType cte;
unsigned long nPrevEndMatch;
char *preEncBuffer;
Dec64Ptr d64state;
DecQPPtr dQPstate;
} PartParseState, *PartParseStatePtr, **PartParseStateHandle;
/* ------------------------------------------------------------------------ */
static Boolean DoCreatePartsOutput(emsMIMEtypeH mimeHdl,
BufTypeHandle inPart1H, BufTypeHandle inPart2H,
createStateHandle hState, short outRef);
static Boolean DoCreateStringOutput(Handle strH, short part, emsMIMEtypeH mimeHdl,
createStateHandle hState, short outRef);
static long DoCreateOnePart(emsMIMEtypeH inPartMimeH, emsMIMEtypeH outMimeH,
TrEncType inPartCTE, short fInRef, short fOutRef,
short part, long preLen, long totalInLen,
createStateHandle hState, emsProgress progressUPP);
static Boolean DoParsePart(BufTypeHandle inBufH, short outRef, emsMIMEtypeH *mimeHdl,
Boolean deMime, PartParseStatePtr pState);
static PartParseStatePtr CreatePartParseState();
static void DeletePartParseState(PartParseStatePtr p);
static void DoBufOutput(short refNum, BufTypeHandle pBuf);
/* ------------------------------------------------------------------------ */
#define kBufferSize (1024)
const StringPtr kMimeVersionStr = "\pMime-Version: 1.0\r\n";
/* ======================================================================
* RFC1847_FileCreate Creates RFC1847 MIME structure.
*
* Args:
* outSpec [IN] Output FSSpec
* outMimeH [IN/OUT] MIME type of output -- boundary param will be added
* inPart1MimeH [IN] MIME type of part 1
* part1CTE [IN] Content-transfer-encoding for part 1
* inPart1Spec [IN] Input FSSpec for part 1 ** READ-ONLY **
* inPart2MimeH [IN] MIME type of part 2
* part2CTE [IN] Content-transfer-encoding for part 2
* inPart2Spec [IN] Input FSSpec for part 2 ** READ-ONLY **
* progressUPP [IN] EMS progress callback procPtr
*
* Returns status.
*/
long RFC1847_FileCreate(const FSSpec *outSpec, emsMIMEtypeH outMimeH,
emsMIMEtypeH inPart1MimeH, TrEncType part1CTE, const FSSpec *inPart1Spec,
emsMIMEtypeH inPart2MimeH, TrEncType part2CTE, const FSSpec *inPart2Spec,
emsProgress progressUPP)
{
short outRefNum, in1RefNum, in2RefNum;
long len, in1Len, in2Len, totalLen, status = FILE1847_OK;
OSErr err;
createStateHandle hState;
err = FSpOpenDF(inPart1Spec, fsRdPerm, &in1RefNum); // input file
err = FSpOpenDF(inPart2Spec, fsRdPerm, &in2RefNum); // signature
err = FSpOpenDF(outSpec, fsRdWrPerm, &outRefNum); // output
if (err != noErr)
status = FILE1847_FAIL;
len = StrLength(kMimeVersionStr);
err = FSWrite(outRefNum, &len, kMimeVersionStr + 1);
if (progressUPP) {
err = GetEOF(in1RefNum, &in1Len);
err = GetEOF(in2RefNum, &in2Len);
totalLen = in1Len + in2Len;
}
hState = NewCreateState();
if (!hState)
status = FILE1847_FAIL;
if (status == FILE1847_OK) // ---------- PART 1 ----------
status = DoCreateOnePart(inPart1MimeH, outMimeH, part1CTE, in1RefNum, outRefNum,
1, 0, totalLen, hState, progressUPP);
if (status == FILE1847_OK) // ---------- PART 2 ----------
status = DoCreateOnePart(inPart2MimeH, outMimeH, part2CTE, in2RefNum, outRefNum,
2, in1Len, totalLen, hState, progressUPP);
if (status == FILE1847_OK) { // Do 1847 cleanup
if (!DoCreatePartsOutput(outMimeH, nil, nil, hState, outRefNum))
status = FILE1847_FAIL;
}
// Do final progress indicator
// if ((!status) && (progressUPP))
// status = (progress(100) ? 1 : 0);
// Done with the state data
DeleteCreateState(hState);
err = FSClose(outRefNum);
err = FSClose(in1RefNum);
err = FSClose(in2RefNum);
return status;
}
/* ======================================================================
* RFC1847_FileParse Parses RFC1847 MIME structure.
*
* Args:
* inSpec [IN] Input FSSpec of file to parse ** READ-ONLY **
* inMimeH [OUT] MIME type of input file
* outPart1Spec [IN] Output FSSpec for part 1 ** WRITE-ONLY **
* outPart1MimeH [OUT] MIME type of created part 1
* part1DeMime [IN] Remove header and transfer encoding, part 1?
* outPart2Spec [IN] Output FSSpec for part 2 ** WRITE-ONLY **
* outPart2MimeH [OUT] MIME type of created part 2
* part2DeMime [IN] Remove header and transfer encoding, part 2?
* progressUPP [IN] EMS progress callback function
*
* Returns status.
* The files names passed in cannot be nil, and must exist.
*/
long RFC1847_FileParse(const FSSpec *inSpec, emsMIMEtypeH *inMimeH,
const FSSpec *outPart1Spec, emsMIMEtypeH *outPart1MimeH, Boolean part1DeMime,
const FSSpec *outPart2Spec, emsMIMEtypeH *outPart2MimeH, Boolean part2DeMime,
emsProgress progressUPP)
{
short inRefNum, out1RefNum, out2RefNum;
Boolean bAbort = false;
long percentComplete, filePos, eofPos, len, ret, status = FILE1847_OK;
Boolean reallyParse1, reallyParse2;
BufTypeHandle outPart1Buf, outPart2Buf, inBuf;
parseStateHandle hState;
PartParseStatePtr pParsePart1State, pParsePart2State;
emsProgressData progData = { sizeof(emsProgressData), 0, nil };
Handle h;
OSErr err;
inRefNum = out1RefNum = out2RefNum = -1;
if (FSpOpenDF(inSpec, fsRdPerm, &inRefNum) != noErr)
return FILE1847_FAIL;
if (FSpOpenDF(outPart1Spec, fsRdWrPerm, &out1RefNum) != noErr) {
status = FILE1847_FAIL;
goto Exit;
}
if (FSpOpenDF(outPart2Spec, fsRdWrPerm, &out2RefNum) != noErr) {
status = FILE1847_FAIL;
goto Exit;
}
outPart1Buf = MakeSize_Buf(kBufferSize);
outPart2Buf = MakeSize_Buf(kBufferSize);
inBuf = MakeSize_Buf(kBufferSize);
if (!outPart1Buf || !outPart2Buf || !inBuf) {
status = FILE1847_FAIL;
goto Exit;
}
// Check to see if we need to parse the parts
reallyParse1 = reallyParse2 = FALSE;
if (outPart1MimeH || part1DeMime)
reallyParse1 = TRUE;
if (outPart1MimeH || part2DeMime)
reallyParse2 = TRUE;
err = GetEOF(inRefNum, &eofPos);
if (progressUPP) { // get the file length of the two input files -- use for progress
progData.value = 0;
if (CallEMSProgressProc(progressUPP, &progData)) {
status = FILE1847_ABORT;
goto Exit2;
}
}
pParsePart1State = CreatePartParseState();
pParsePart2State = CreatePartParseState();
hState = NewParseState();
if ((pParsePart1State) && (pParsePart2State) && (hState)) {
do {
/* Fill the input buffer from the input file */
EmptyBuf_Buf(inBuf);
len = BufSize_Buf(inBuf);
h = GetBuf_Buf(inBuf);
HLock(h);
err = FSRead(inRefNum, &len, *h);
HUnlock(h);
if (err != noErr && err != eofErr)
break;
SetLen_Buf(inBuf, len);
/* Parse the input, producing output until completed input */
do {
EmptyBuf_Buf(outPart1Buf);
EmptyBuf_Buf(outPart2Buf);
ret = RFC1847_Parse(inMimeH, outPart1Buf, outPart2Buf, inBuf, hState);
if (ret != RFC1847_FAIL) {
if (reallyParse1) { /* Parse part #1 */
if (!DoParsePart(outPart1Buf, out1RefNum, outPart1MimeH, part1DeMime, pParsePart1State))
status = FILE1847_FAIL;
}
else /* Raw output part #1 */
DoBufOutput(out1RefNum, outPart1Buf);
if (reallyParse2) { /* Parse part #2 */
if (!DoParsePart(outPart2Buf, out2RefNum, outPart2MimeH, part2DeMime, pParsePart2State))
status = FILE1847_FAIL;
}
else /* Raw output part #2 */
DoBufOutput(out2RefNum, outPart2Buf);
}
} while ((status == FILE1847_OK) && (ret == RFC1847_BUFFERFULL));
if (ret == RFC1847_FAIL)
status = FILE1847_FAIL;
err = GetFPos(inRefNum, &filePos);
if ((status == FILE1847_OK) && (progressUPP)) {
percentComplete = (filePos * 100) / eofPos;
progData.value = percentComplete;
if (CallEMSProgressProc(progressUPP, &progData))
status = FILE1847_ABORT;
}
} while ((status == FILE1847_OK) && (filePos < eofPos));
if (status == FILE1847_OK) {
if (reallyParse1) /* Parse part #1 */
if (!DoParsePart(nil, out1RefNum, outPart1MimeH, part1DeMime, pParsePart1State))
status = FILE1847_FAIL;
if (reallyParse2) /* Parse part #2 */
if (!DoParsePart(nil, out2RefNum, outPart2MimeH, part2DeMime, pParsePart2State))
status = FILE1847_FAIL;
}
}
else
status = FILE1847_FAIL;
DeletePartParseState(pParsePart1State);
DeletePartParseState(pParsePart2State);
DeleteParseState(hState);
Exit2:
Delete_Buf(outPart1Buf);
Delete_Buf(outPart2Buf);
Delete_Buf(inBuf);
Exit:
if (inRefNum != -1)
err = FSClose(inRefNum);
if (out1RefNum != -1)
err = FSClose(out1RefNum);
if (out2RefNum != -1)
err = FSClose(out2RefNum);
return status;
}
#pragma mark -
/* ------------------------------------------------------------------------ */
static Boolean DoCreatePartsOutput(emsMIMEtypeH mimeHdl,
BufTypeHandle inPart1H, BufTypeHandle inPart2H,
createStateHandle hState, short outRef)
{
BufTypeHandle outBufH;
unsigned long outLen, status;
OSErr err;
long len;
Handle h;
if (inPart1H)
ResetPos_Buf(inPart1H);
if (inPart2H)
ResetPos_Buf(inPart2H);
outBufH = MakeSize_Buf(kBufferSize);
do {
EmptyBuf_Buf(outBufH); // Clear the output
status = RFC1847_Create(mimeHdl, outBufH, inPart1H, inPart2H, hState);
if ((outLen = BufLen_Buf(outBufH)) > 0) { // Output whatever we got
h = GetBuf_Buf(outBufH);
HLock(h);
len = BufLen_Buf(outBufH);
err = FSWrite(outRef, &len, *h); // + pos
HUnlock(h);
if (err) {
status = RFC1847_FAIL;
break;
}
}
} while (status == RFC1847_BUFFERFULL);
Delete_Buf(outBufH);
return (status != RFC1847_FAIL);
}
/* ------------------------------------------------------------------------ */
static Boolean DoCreateStringOutput(Handle strH, short part, emsMIMEtypeH mimeHdl,
createStateHandle hState, short outRef)
{
BufTypeHandle bufH;
long status = RFC1847_FAIL;
bufH = Make_Buf();
if (bufH) {
// Manually setup the buffer structure -- kind of ugly, but
// more efficient than copying the string
(**bufH).bufHandle = strH;
(**bufH).len = GetHandleSize(strH);
ResetPos_Buf(bufH);
// Now output the buffer
if (part == 1)
status = DoCreatePartsOutput(mimeHdl, bufH, nil, hState, outRef);
else
status = DoCreatePartsOutput(mimeHdl, nil, bufH, hState, outRef);
Clear_Buf(bufH); // Unassociate buffer with string
Delete_Buf(bufH); // Delete buffer struct -- AFTER we clear it's contents
}
return (status != RFC1847_FAIL);
}
/* ------------------------------------------------------------------------ */
static long DoCreateOnePart(emsMIMEtypeH inPartMimeH, emsMIMEtypeH outMimeH,
TrEncType inPartCTE, short fInRef, short fOutRef,
short part, long preLen, long totalInLen,
createStateHandle hState, emsProgress progressUPP)
{
BufTypeHandle inBufH;
Handle hCT, hCTE, crlfH;
char *preEncBuffer = nil;
unsigned long preEncBufLen;
Enc64Ptr e64state = nil; // Used by Encode64()
EncQPPtr eQPstate = nil; // Used by EncodeQP()
long status, filePos, eofPos, len, readLen;
short failed;
OSErr err;
emsProgressData progData = { sizeof(emsProgressData), 0, nil };
inBufH = MakeSize_Buf(kBufferSize);
if (!inBufH)
return FILE1847_FAIL;
status = FILE1847_OK;
PtrToHand("\r\n", &crlfH, 2);
// Do InPartMimePtr (Content-Type) header
if ((status == FILE1847_OK) && (inPartMimeH)) {
hCT = StringMimeType(inPartMimeH);
if (hCT) {
if (!DoCreateStringOutput(hCT, part, outMimeH, hState, fOutRef))
status = FILE1847_FAIL;
else if (!DoCreateStringOutput(crlfH, part, outMimeH, hState, fOutRef))
status = FILE1847_FAIL;
DisposeHandle(hCT);
}
else
status = FILE1847_FAIL;
}
// Do inPartCTE (Content-Transfer-Encoding) header
if ((status == FILE1847_OK) && (inPartCTE != CTE_NONE)) {
hCTE = RFC822_MakeCTE(inPartCTE);
if (hCTE) {
if (!DoCreateStringOutput(hCTE, part, outMimeH, hState, fOutRef))
status = FILE1847_FAIL;
else if (!DoCreateStringOutput(crlfH, part, outMimeH, hState, fOutRef))
status = FILE1847_FAIL;
DisposeHandle(hCTE);
}
else
status = FILE1847_FAIL;
}
// Do blank line -- only if we put out some header already
if ((status == FILE1847_OK) && ((inPartMimeH) || (inPartCTE != CTE_NONE))) {
if (!DoCreateStringOutput(crlfH, part, outMimeH, hState, fOutRef))
status = FILE1847_FAIL;
}
if (status == FILE1847_OK) {
switch (inPartCTE) {
case CTE_Base64: // BASE64
// BASE64 expands about 1/3
preEncBufLen = ((kBufferSize * 6) / 10);
preEncBuffer = NewPtr(preEncBufLen);
if (!preEncBuffer)
status = FILE1847_FAIL; // Could not create buffer
e64state = (Enc64Ptr) NewPtr(sizeof(Enc64)); // Used by Encode64()
e64state->partialCount = e64state->bytesOnLine = 0;
break;
case CTE_QP: // QUOTED-PRINTABLE
// QP expands max of 3 times
preEncBufLen = (kBufferSize / 4);
preEncBuffer = NewPtr(preEncBufLen);
if (!preEncBuffer)
status = FILE1847_FAIL; // Could not create buffer
eQPstate = (EncQPPtr) NewPtr(sizeof(EncQP)); // Used by EncodeQP()
eQPstate->nCurLineLen = 0;
eQPstate->cLastChar = '\0';
break;
default: // Otherwise, no encoding
preEncBufLen = 0;
}
}
// Do pInPartFilename
while (status == FILE1847_OK) {
EmptyBuf_Buf(inBufH);
Lock_Buf(inBufH);
switch (inPartCTE) {
case CTE_Base64:
readLen = preEncBufLen;
err = FSRead(fInRef, &readLen, preEncBuffer);
len = preEncBufLen;
failed = Encode64((UPtr) preEncBuffer, readLen,
(UPtr) *GetBuf_Buf(inBufH), &len, e64state);
readLen = len;
break;
case CTE_QP:
readLen = preEncBufLen;
err = FSRead(fInRef, &readLen, preEncBuffer);
len = preEncBufLen;
failed = EncodeQP((UPtr) preEncBuffer, readLen,
(UPtr) *GetBuf_Buf(inBufH), &len, (long*) eQPstate);
readLen = len;
break;
default: /* 7bit, 8bit, binary, none */
readLen = BufSize_Buf(inBufH);
err = FSRead(fInRef, &readLen, *GetBuf_Buf(inBufH));
break;
}
Unlock_Buf(inBufH);
if (readLen > 0) {
SetLen_Buf(inBufH, readLen);
if (part == 1) {
if (!DoCreatePartsOutput(outMimeH, inBufH, nil, hState, fOutRef))
status = FILE1847_FAIL;
}
else {
if (!DoCreatePartsOutput(outMimeH, nil, inBufH, hState, fOutRef))
status = FILE1847_FAIL;
}
}
if (progressUPP) { // Update the progress and check for abort
err = GetFPos(fInRef, &filePos);
progData.value = (((filePos + preLen) * 100L) / totalInLen);
if (CallEMSProgressProc(progressUPP, &progData)) {
status = FILE1847_ABORT;
goto Exit;
}
}
err = GetFPos(fInRef, &filePos);
err = GetEOF(fInRef, &eofPos);
if (filePos >= eofPos)
break;
}
// Finish part -- if needed
if (status == FILE1847_OK) {
switch (inPartCTE) {
case CTE_Base64:
readLen = BufSize_Buf(inBufH);
failed = Encode64(nil, 0, (UPtr) *GetBuf_Buf(inBufH), &readLen, e64state);
break;
case CTE_QP:
readLen = BufSize_Buf(inBufH);
failed = EncodeQP(nil, 0, (UPtr) *GetBuf_Buf(inBufH), &readLen, (long*) eQPstate);
break;
default: /* 7bit, 8bit, binary, none */
readLen = 0;
}
if (readLen > 0) {
SetLen_Buf(inBufH, readLen);
if (part == 1) {
if (!DoCreatePartsOutput(outMimeH, inBufH, nil, hState, fOutRef))
status = FILE1847_FAIL;
}
else {
if (!DoCreatePartsOutput(outMimeH, nil, inBufH, hState, fOutRef))
status = FILE1847_FAIL;
}
}
}
Exit:
if (e64state != nil)
DisposePtr((Ptr) e64state);
if (eQPstate != nil)
DisposePtr((Ptr) eQPstate);
if (preEncBuffer != nil)
DisposePtr(preEncBuffer);
Delete_Buf(inBufH);
DisposeHandle(crlfH);
return status;
}
/* ------------------------------------------------------------------------ */
static Boolean DoParsePart(BufTypeHandle inBufH, short outRef, emsMIMEtypeH *mimeHdl,
Boolean deMime, PartParseStatePtr pState)
{
unsigned short nLen, newMatched;
short failed;
char *pHeader, *pCT, *pCTE;
long len, errorcnt, nSkip, nRemain, preEncBufLen;
Handle h;
OSErr err;
if (!inBufH) { // Input buf nil indicates 'cleanup'
return (pState->bFoundHeader);
}
if (!pState->bFoundHeader) {
ResetPos_Buf(pState->searchBufH);
if (pState->nPrevEndMatch > 0) { /* Check for completion of span */
// If doesn't continue match, returns zero
// otherwise returns number of chars of searchBufH that have been matched
newMatched = CompleteCount_Buf(inBufH, pState->searchBufH, pState->nPrevEndMatch);
if (newMatched == BufLen_Buf(pState->searchBufH)) { /* complete match made */
pState->bFoundHeader = true;
pState->nPrevEndMatch = 0;
BufNCat_Buf(pState->bufH, inBufH, (BufLen_Buf(pState->searchBufH) - (pState->nPrevEndMatch)));
}
else if (newMatched != 0) { /* Continued to match, but not completed yet -- the input buffer is smaller than the searchBufH */
BufNCat_Buf(pState->bufH, inBufH, PosLen_Buf(inBufH));
pState->nPrevEndMatch = newMatched;
return true;
}
else { /* No match continuation */
pState->nPrevEndMatch = 0;
}
}
ResetPos_Buf(pState->searchBufH);
// Still not found -- no span
if (!pState->bFoundHeader) {
// Find match of searchBufH, either complete or end-spanning
// return number of chars to skip before match
nSkip = SkipCount_Buf(inBufH, pState->searchBufH);
nRemain = PosLen_Buf(inBufH) - nSkip;
if (nRemain == 0) { // Not found
BufNCat_Buf(pState->bufH, inBufH, PosLen_Buf(inBufH));
return true;
}
else if (nRemain > BufLen_Buf(pState->searchBufH)) { /* Found 'complete' */
pState->bFoundHeader = true;
BufNCat_Buf(pState->bufH, inBufH, (nSkip + BufLen_Buf(pState->searchBufH)));
}
else { // Partial possible
pState->nPrevEndMatch = nRemain;
BufNCat_Buf(pState->bufH, inBufH, PosLen_Buf(inBufH));
return true;
}
}
// ---------- Now we know it is found ----------
nLen = BufLen_Buf(pState->bufH);
pHeader = NewPtr(nLen + 1);
strncpy(pHeader, *GetBuf_Buf(pState->bufH), nLen);
pCT = RFC822_ExtractHeader(pHeader, kContentTypeHdrCStr);
if (mimeHdl)
*mimeHdl = ParseMakeMimeType(pCT);
if (deMime) {
pCTE = RFC822_ExtractCTE(pHeader);
if (pCTE)
pState->cte = RFC822_ParseCTE(pCTE);
else
pState->cte = CTE_NONE; /* No CTE header, so no encoding */
switch (pState->cte) {
case CTE_Base64: // BASE64 expands about 1/3
preEncBufLen = ((kBufferSize * 10) / 6);
pState->preEncBuffer = NewPtr(preEncBufLen);
pState->d64state = (Dec64Ptr) NewPtrClear(sizeof(Dec64)); // Used by Decode64()
break;
case CTE_QP: // QP expands max of 3 times
preEncBufLen = (kBufferSize * 4);
pState->preEncBuffer = NewPtr(preEncBufLen);
pState->dQPstate = (DecQPPtr) NewPtrClear(sizeof(EncQP));
pState->dQPstate->state = qpNormal;
break;
// Otherwise, no encoding
default: // Otherwise, no encoding
;
}
}
else {
len = nLen;
h = GetBuf_Buf(pState->bufH);
HLock(h);
err = FSWrite(outRef, &len, *h);
HUnlock(h);
}
Free_Buf(pState->bufH);
}
// ---------- Now we know it is found and header is init'd ----------
Lock_Buf(inBufH);
switch (pState->cte) {
case CTE_Base64:
len = preEncBufLen;
failed = Decode64((UPtr) GetPos_Buf(inBufH), PosLen_Buf(inBufH),
(UPtr) pState->preEncBuffer, &len, pState->d64state, &errorcnt);
err = FSWrite(outRef, &len, pState->preEncBuffer);
break;
case CTE_QP:
len = preEncBufLen;
failed = DecodeQP((UPtr) GetPos_Buf(inBufH), PosLen_Buf(inBufH),
(UPtr) pState->preEncBuffer, &len, pState->dQPstate, &errorcnt);
err = FSWrite(outRef, &len, pState->preEncBuffer);
break;
default: /* 7bit, 8bit, binary, none */
len = PosLen_Buf(inBufH);
err = FSWrite(outRef, &len, GetPos_Buf(inBufH));
break;
}
Unlock_Buf(inBufH);
return true;
}
#pragma mark -
/* ------------------------------------------------------------------------ */
static PartParseStatePtr CreatePartParseState(void)
{
PartParseStatePtr p;
p = (PartParseStatePtr) NewPtr(sizeof(PartParseState));
if (p) {
p->bFoundHeader = false;
p->bufH = Make_Buf();
p->searchBufH = Make_Buf();
StrCpy_Buf(p->searchBufH, "\p\r\n\r\n");
p->cte = CTE_NONE;
p->nPrevEndMatch = 0;
p->preEncBuffer = nil;
p->d64state = nil;
p->dQPstate = nil;
}
return p;
}
/* ------------------------------------------------------------------------ */
static void DeletePartParseState(PartParseStatePtr p)
{
if (p) {
Delete_Buf(p->bufH);
Delete_Buf(p->searchBufH);
DisposePtr((Ptr) p->preEncBuffer);
DisposePtr((Ptr) p->d64state);
DisposePtr((Ptr) p->dQPstate);
DisposePtr((Ptr) p);
}
}
/* ======================================================================
* DoBufOutput (static)
*
* Private function used to output a buffer.
*/
static void DoBufOutput(short refNum, BufTypeHandle pBuf)
{
long len;
Handle h;
len = PosLen_Buf(pBuf);
h = GetBuf_Buf(pBuf);
HLock(h);
FSWrite(refNum, &len, *h);
HUnlock(h);
}